#include "sdb.h"

#define NR_WP 32

typedef struct watchpoint {
  int NO;
  struct watchpoint *next;
  char exp[32];
  word_t value;

  /* TODO: Add more members if necessary */

} WP;

//head用于组织使用中的监视点结构
//free_用于组织空闲的监视点结构
//init_wp_pool()函数会对两个链表进行初始化

static WP wp_pool[NR_WP] = {};
static WP *head = NULL, *free_ = NULL;

void init_wp_pool() {
  int i;
  for (i = 0; i < NR_WP; i ++) {
    wp_pool[i].NO = i;
    wp_pool[i].next = (i == NR_WP - 1 ? NULL : &wp_pool[i + 1]);
  }

  head = NULL;
  free_ = wp_pool;
}

/* TODO: Implement the functionality of watchpoint */

//new_wp()从free_链表中返回一个空闲的监视点结构
WP* new_wp(char * exp){
	assert(free_ != NULL);
	WP *temp = free_;
	free_ = free_->next;
	temp->next = NULL;

	bool success = false;
	strcpy(temp->exp, exp);
	temp->value = expr(temp->exp, &success);
	assert(success);

	if(head==NULL)
		head = temp;
	else{
		WP *p = head;
		while(p->next)
			p = p->next;
		p->next = temp;
	}
	return temp;
}

//free_wp()将wp归还到free_链表中
int free_wp(WP *wp){
	if(wp == NULL)
	    printf("Input something!\n");
	if(wp == head)
	    head = head -> next;
	else{
	   	WP *p = head;
	   	while(p->next!=wp)
	   		p = p->next;
	   	if(p == NULL)
	   	    return 0;
	   	p -> next = wp -> next;
	}
	wp -> next = free_;
	free_ = wp;
  return 1;
}

//删除监视点
int delete_wp( int num){
  if( head == NULL){
    printf("Input something!\n");
    return 0;
  }
  else{
    WP *p = head;
    while(p->next != NULL){
      if(p ->NO == num){
        free_wp(p);
        return 1;
      }
      else p = p->next;
    }
    if(p ->NO == num){
        free_wp(p);
        return 1;
    }
    return 0;
  }
}

int test_change(){
  bool success;
  /*
  for(int i=0 ; i< NR_WP; i++){
    if(expr(wp_pool[i].exp , &success) != wp_pool[i].value)
    return 1;
  }*/
  if( head == NULL){
    //printf("Input something!\n");
    return 0;
  }
  else{
    WP *p = head;
    while(p->next != NULL){
      if(expr(p -> exp , &success) != p -> value){
        printf("watchpoint old NO.%d, exp:%s, DEC: %ld,\
          HEX: 0x%016lx\n",p->NO, p->exp, p->value, p->value);
        p->value = expr(p -> exp , &success);
        printf("watchpoint new NO.%d, exp:%s, DEC: %ld,\
          HEX: 0x%016lx\n",p->NO, p->exp, p->value, p->value);
        return 1;
      }
      p = p->next;
    }
    if(expr(p -> exp, &success) != p -> value){
      printf("watchpoint old NO.%d, exp:%s, DEC: %ld,\
          HEX: 0x%016lx\n",p->NO, p->exp, p->value, p->value);
        p->value = expr(p -> exp , &success);
      printf("watchpoint new NO.%d, exp:%s, DEC: %ld,\
          HEX: 0x%016lx\n",p->NO, p->exp, p->value, p->value);
      return 1;
    }          
  }
  return 0;
}


//遍历wp_pool打印
/*
void print_wp(){
  for(int i=0 ; i< NR_WP; i++){
    if( strcmp(wp_pool[i].exp,""))
    printf("wp_pool num %d, NO:%d, exp:%s, value: %ld\n",\
     i, wp_pool[i].NO, wp_pool[i].exp, wp_pool[i].value);
  }
}*/

//顺着链接打印
void print_wp(){
  if( head == NULL)
    printf("Input something!\n");
  else{
    WP *p = head;
    while(p->next != NULL){
      printf("watchpoint NO.%d, exp:%s, DEC: %ld,\
          HEX: 0x%016lx\n",p->NO, p->exp, p->value, p->value);
      p = p->next;
    }
    printf("watchpoint NO.%d, exp:%s, DEC: %ld,\
          HEX: 0x%016lx\n",p->NO, p->exp, p->value, p->value);
  }
}



